x86: Always respect guest setting CR4.TSD
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 26 Nov 2009 11:24:50 +0000 (11:24 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 26 Nov 2009 11:24:50 +0000 (11:24 +0000)
Also fix guest reads of CR4.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/time.c
xen/arch/x86/traps.c

index ffe1ab8187da1636ab329267ec9fe35d4127a60c..c58ba5784f4d92b765f9be097c4ccff95e02bd3d 100644 (file)
@@ -1640,7 +1640,7 @@ void pv_soft_rdtsc(struct vcpu *v, struct cpu_user_regs *regs, int rdtscp)
 
     if ( rdtscp )
          regs->ecx =
-             (d->arch.tsc_mode == TSC_MODE_PVRDTSCP) ?  d->arch.incarnation : 0;
+             (d->arch.tsc_mode == TSC_MODE_PVRDTSCP) ? d->arch.incarnation : 0;
 }
 
 static int host_tsc_is_safe(void)
index 9ccb769748ea82eee8dc9d64806ea2045c823e25..aebbd9b4f207c825cd84e73eef13cce85178959b 100644 (file)
@@ -2034,9 +2034,7 @@ static int emulate_privileged_op(struct cpu_user_regs *regs)
      * are executable only from guest kernel mode (virtual ring 0).
      */
     opcode = insn_fetch(u8, code_base, eip, code_limit);
-    if ( !guest_kernel_mode(v, regs) &&
-         (opcode != 0x1) && /* always emulate rdtscp */
-         !((opcode == 0x31) && v->domain->arch.vtsc) )
+    if ( !guest_kernel_mode(v, regs) && (opcode != 0x1) && (opcode != 0x31) )
         goto fail;
 
     if ( lock && (opcode & ~3) != 0x20 )
@@ -2044,6 +2042,9 @@ static int emulate_privileged_op(struct cpu_user_regs *regs)
     switch ( opcode )
     {
     case 0x1: /* RDTSCP */
+        if ( (v->arch.guest_context.ctrlreg[4] & X86_CR4_TSD) &&
+             !guest_kernel_mode(v, regs) )
+            goto fail;
         if ( insn_fetch(u8, code_base, eip, code_limit) != 0xf9 )
             goto fail;
         pv_soft_rdtsc(v, regs, 1);
@@ -2093,12 +2094,7 @@ static int emulate_privileged_op(struct cpu_user_regs *regs)
             break;
 
         case 4: /* Read CR4 */
-            /*
-             * Guests can read CR4 to see what features Xen has enabled. We
-             * therefore lie about PGE and PSE as they are unavailable to
-             * guests.
-             */
-            *reg = read_cr4() & ~(X86_CR4_PGE|X86_CR4_PSE);
+            *reg = v->arch.guest_context.ctrlreg[4];
             break;
 
         default:
@@ -2297,7 +2293,13 @@ static int emulate_privileged_op(struct cpu_user_regs *regs)
     }
 
     case 0x31: /* RDTSC */
-        pv_soft_rdtsc(v, regs, 0);
+        if ( (v->arch.guest_context.ctrlreg[4] & X86_CR4_TSD) &&
+             !guest_kernel_mode(v, regs) )
+            goto fail;
+        if ( v->domain->arch.vtsc )
+            pv_soft_rdtsc(v, regs, 0);
+        else
+            rdtsc(regs->eax, regs->edx);
         break;
 
     case 0x32: /* RDMSR */